home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
EVENT.C
< prev
next >
Wrap
Text File
|
1993-08-09
|
13KB
|
474 lines
/*======================================================================*
* File Name: event.c *
* Purpose : Some rough event handling for smtp *
* *
* Date Name Description *
* ---- ---- ----------- *
* 25-Jul-1991 DK5DC initial *
* 04-Sep-1991 DK5DC added Autorun *
* 05-Oct-1991 DK5DC initial 'at' *
* xx-Nov-1992 DB3FL some enhancements *
*=======================================================================*/
#include "config.h"
#include <dos.h>
#include <ctype.h>
#include "global.h"
#include "session.h"
#include "socket.h"
#include "usock.h"
#include "netuser.h"
#include "ax25.h"
#include "smtp.h"
#include "cmdparse.h"
#include "arp.h"
#include "dirutil.h"
#include "commands.h"
#include "event.h"
/*----------------------------------------------------------------------*
* main Control block hook *
*-----------------------------------------------------------------------*/
static Event *Delv = NULL;
struct proc *Eproc = NULLPROC;
#define MINSPERDAY 1440
int EVwait = 0;
int EMinute = 0;
static char *Dsstring[] = {
"Window","Suspended","Auto","Running","Autorun",
"Autowait","OneShot","Interval",
};
/*----------------------------------------------------------------------*
* This subroutine is called from within smtptick. It checks the *
* destination address against the control blocks to decide wether *
* sending mail is allowed or not. *
*-----------------------------------------------------------------------*/
int
testdelv(int32 dest)
{
Event *ep;
int found = FALSE;
for(ep = Delv; ep; ep = ep->next) {
if(ep->host == dest) {
found = TRUE;
if(ep->state == Running) {
return TRUE;
}
break;
}
}
if(found) {
return FALSE;
}
return TRUE; /* target not in list, kick anyway*/
}
/*----------------------------------------------------------------------*
* Check for open tcp connctions *
*-----------------------------------------------------------------------*/
static struct tcb * near
check_tcp(Event *ep)
{
struct tcb *tcb;
for(tcb = Tcbs; tcb != NULLTCB; tcb = tcb->next) {
if(tcb->conn.remote.address == ep->host &&
tcb->conn.remote.port == ep->port) {
return tcb;
}
}
return 0;
}
/*----------------------------------------------------------------------*
* retrieve the Event block whose segment address is passed *
*-----------------------------------------------------------------------*/
static Event * near
getep(int argc,char **argv,int flag)
{
Event *ep, *epr = (Event *)shtop(argv[1]);
if(isdigit(*argv[1])) {
for(ep = Delv; ep; ep = ep->next) {
if (ep == epr) {
break;
}
}
} else {
char *name = cxallocw(argc,20);
while(--argc > 0) {
strcat(name,*++argv);
strcat(name," ");
}
for(ep = Delv; ep; ep = ep->next) {
if(strnicmp(ep->file,name,strlen(name) - 1) == 0) {
break;
}
}
xfree(name);
}
if(ep == 0) {
tputs(Notval);
return 0;
}
if(flag == TRUE) {
tputs("Use 'event drop'\n");
return 0;
}
return ep;
}
/*----------------------------------------------------------------------*
* Check time for validity *
*-----------------------------------------------------------------------*/
static int near
chktime(char *from)
{
int fh = 0, fm = 0;
char *cp = from;
if(*cp++ == '+') {
return atoi(cp);
}
if((sscanf(from,"%d:%d",&fh,&fm)) == 2) {
fh = fh * 60 + fm;
if(fh >= 0 && fh <= MINSPERDAY) {
return fh;
}
}
return -1;
}
static char * near
formtime(int t)
{
static char buf[6];
int mins, hrs, ti = t;
mins = ti % 60;
ti /= 60;
hrs = ti % 60;
sprintf(buf,"%02d:%02d",hrs,mins);
return buf;
}
/*----------------------------------------------------------------------*
* this function is called every time a given window closes *
*-----------------------------------------------------------------------*/
static void near
deltimeout(void *p)
{
Event *ep = (Event *)p;
struct tcb *tcb;
ep->state = Wait; /* clear timer */
if((tcb = check_tcp(ep)) != 0) {
reset_tcp(tcb); /* reset any connection */
}
return;
}
static void near
delevent(Event *ep)
{
char c;
Current->ttystate.echo = Current->ttystate.edit = 0;
c = keywait("Warning! Running event, connection will be closed! Remove (y/n)? ",0);
Current->ttystate.echo = Current->ttystate.edit = 1;
if(c == 'y') {
deltimeout(ep); /* reset running connection */
}
}
/*----------------------------------------------------------------------*
* Build an event control block. This control block may have *
* different formats. *
*-----------------------------------------------------------------------*/
static int
doEventadd(int argc,char **argv,void *p)
{
int time;
Event *ep = mxallocw(sizeof(struct event));
argc--;
argv++;
if((time = chktime(*argv)) != -1) { /* 1st arg time? */
ep->state = Atoneshot;
ep->from = time;
if(**argv == '+') {
ep->from += EMinute;
}
argc--;
argv++;
}
if((time = chktime(*argv)) != -1) { /* 1st/2nd arg time? */
ep->state = Wait;
ep->to = time;
if(**argv == '+') {
ep->to += ep->from;
}
argc--;
argv++;
}
if(strchr(*argv,':') == NULL /* 1st/2nd/3rd arg interval? */
&& isdigit(**argv)
&& (time = atoi(*argv)) > 0
&& time <= MINSPERDAY) {
ep->state = Atinterval;
ep->interval = time;
argc--;
argv++;
}
if(argc < 0
|| (ep->state == Atinterval
&& (ep->interval == 0
|| (ep->to && (ep->interval > (ep->to - ep->from)))))
|| (ep->to && ep->to < ep->from)) {
tputs("Illegal time or syntax error\n");
xfree(ep);
return -1;
}
if(ep->state == Atinterval && !ep->from) {
ep->from = EMinute;
}
if((ep->minute = ep->from + ep->interval) > MINSPERDAY) {
ep->minute -= MINSPERDAY;
}
if(ep->state == Wait) {
if((ep->host = resolve(*argv)) == 0) {
tprintf(Badhost,*argv);
return -1;
}
ep->file = strxdup(*argv);
} else {
ep->file = cxallocw(argc + 1,20);
while(argc-- > 0) {
strcat(ep->file,*argv++);
strcat(ep->file," ");
}
}
/*-------------------------------------------------------------------*
* seems that all the entries are correct, go connect the entry *
*--------------------------------------------------------------------*/
ep->next = Delv;
Delv = ep;
return 0;
}
/*----------------------------------------------------------------------*
* Activate a previously suspended event. Must not be of type Auto *
*-----------------------------------------------------------------------*/
static int
doEactivate(int argc,char **argv,void *p)
{
Event *ep;
if((ep = getep(argc,argv,TRUE)) != 0) {
if(ep->state == Suspended) {
ep->state = Wait;
}
}
return 0;
}
/*----------------------------------------------------------------------*
* drop an event from the list *
*-----------------------------------------------------------------------*/
static int
doEdrop(int argc,char **argv,void *p)
{
Event *ep, *epp = 0, *epr;
if((ep = getep(argc,argv,FALSE)) != 0) {
if(ep->state == Running || ep->state == Autorun) {
delevent(ep);
}
epr = ep;
for(ep = Delv; ep; ep = ep->next) {
if(epr == ep) {
if(ep == Delv) {
Delv = ep->next;
} else {
epp->next = ep->next;
}
xfree(ep->file);
xfree(ep);
return 0;
}
epp = ep;
}
}
return 0;
}
/*----------------------------------------------------------------------*
* List event entries. Derived from the other list functions in the *
* package. *
*-----------------------------------------------------------------------*/
static int
doElist(int argc,char **argv,void *p)
{
Event *ep = 0;
static char s[] = " ";
/*-------------------------------------------------------------------*
* display events *
*--------------------------------------------------------------------*/
tputs("&EVCB Status From To Next Time Cmd\n");
for(ep = Delv; ep; ep = ep->next) {
tprintf("%-7x",ptol(ep));
tprintf("%-10s",Dsstring[ep->state]);
if((ep->from && ep->state != Atinterval)
|| (ep->state == Atinterval && ep->to)) {
tprintf("%-7s",formtime(ep->from));
} else {
tputs(s);
}
if(ep->to) {
tprintf("%-7s",formtime(ep->to));
} else {
tputs(s);
}
if(ep->state == Atinterval) {
tprintf("%-7s%-7d",formtime(ep->minute),ep->interval);
} else {
tputs(s);
tputs(s);
}
tprintf("%s\n",ep->file);
}
return 0;
}
/*----------------------------------------------------------------------*
* Stop a running event, but don't remove *
*-----------------------------------------------------------------------*/
static int
doEstop(int argc,char **argv,void *p)
{
Event *ep;
if((ep = getep(argc,argv,TRUE)) != 0) {
if(ep->state == Running) {
delevent(ep);
}
}
return 0;
}
/*----------------------------------------------------------------------*
* Suspend an event *
*-----------------------------------------------------------------------*/
static int
doEsuspend(int argc,char **argv,void *p)
{
Event *ep;
if((ep = getep(argc,argv,TRUE)) != 0) {
if(ep->state == Running) {
delevent(ep);
}
ep->state = Suspended;
}
return 0;
}
int
doevent(int argc,char **argv,void *p)
{
struct cmds Evtcmds[] = {
{"add", doEventadd, 0, 3, "event add <hh:mm>|<interval> <command> [arg]"},
{"activate", doEactivate, 0, 2, "event activate <evcb>"},
{"drop", doEdrop, 0, 2, "event drop <evcb>"},
{"list", doElist, 0, 0, NULLCHAR},
{"stop", doEstop, 0, 2, "event stop <evcb>"},
{"suspend", doEsuspend, 0, 2, "event suspend <evcb>"},
{NULLCHAR, NULLFP, 0, 0, NULLCHAR}
};
return subcmd(Evtcmds,argc,argv,p);
}
/*----------------------------------------------------------------------*
* The event process. This process is called every minute by the *
* statline process. The only parameter passed is the actual *
* minute. (Note that the alert/pwait pair has been changed to accept *
* a void * systemwide, which give a more flexible way to pass *
* more than just an integer information
*-----------------------------------------------------------------------*/
void
event(int i,void *v1,void *v2)
{
Event *ep;
Dstate state;
Eproc = Curproc;
for(; ;) {
if(EVwait != 0) {
EVwait--;
}
EMinute = (int)pwait(&state);
EVwait++;
/*--------------------------------------------------------------*
* scan structures for any job to to *
*---------------------------------------------------------------*/
for(ep = Delv; ep; ep = ep->next) {
switch (ep->state) {
case Wait:
if(EMinute >= ep->from && EMinute < ep->to) {
/* got one */
ep->state = Running;
smtptick((void *)ep->host);
pwait(NULL);
}
break;
case Running:
if(ep->state == Running && ep->to < EMinute) {
deltimeout(ep);
pwait(NULL);
}
break;
case Atinterval:
if(ep->from && ep->to
&& (EMinute < ep->from || EMinute >= ep->to)) {
ep->minute = ep->from;
continue;
}
default:
if(EMinute == ep->minute) {
char *cp = strxdup(ep->file);
log(-1,9985,cp);
cmdparse(Cmds,cp,0);
xfree(cp);
if(ep->state == Atinterval) {
if((ep->minute += ep->interval) > MINSPERDAY)
ep->minute -= MINSPERDAY;
}
}
break;
}
}
}
}